#include "Viewport.h"

#include "SceneView.h"
#include "Runtime/CGI/CGICommandList.h"
#include "Runtime/CGI/DynamicCGI.h"
#include "Runtime/Logic/Engine.h"
#include "Runtime/Rendering/RendererInterface.h"
#include "Application.h"
#include "ViewportClient.h"
#include "2D/SlaveRenderer.h"
#include "2D/Widget.h"
#include "Runtime/Thread/RenderingThreadContext.h"

namespace Alice{
    Viewport::Viewport(ViewportClient* inViewportClient)
        :mViewportClient(inViewportClient)
    {
    }

    void Viewport::EnqueueBeginRenderFrame(const bool bShouldPresent)
    {
        ENQUEUE_RENDER_COMMAND(BeginRenderFrame)([&](CGICommandListImmediate&inCGICommandList)
        {
            BeginRenderFrame(inCGICommandList);
        });
    }
    void Viewport::EnqueueEndRenderFrame(const bool bShouldPresent,const bool bLockToVsync)
    {
        ENQUEUE_RENDER_COMMAND(EndRenderFrame)([&](CGICommandListImmediate&inCGICommandList)
        {
            EndRenderFrame(inCGICommandList,bShouldPresent,bLockToVsync);
        });
    }
    void Viewport::BeginRenderFrame(CGICommandListImmediate& RHICmdList)
    {
        uint32 imageIndex=0;
        mCGIRenderTargetTexture=RHIGetViewportBackBuffer(mCGIViewport.GetPtr(),imageIndex).mPtr;
    }
    void Viewport::EndRenderFrame(CGICommandListImmediate& RHICmdList, bool bPresent, bool bLockToVsync)
    {
        RHICmdList.EndDrawingViewport(mCGIViewport.GetPtr(),true,true);
    }
    void Viewport::Draw(bool bShouldPresent)
    {
        EnqueueBeginRenderFrame(bShouldPresent);
        mViewportClient->Draw(this);
        EnqueueEndRenderFrame(bShouldPresent,true);
    }

    SceneViewport::SceneViewport(ViewportClient*inViewportClient,ViewportWidget* inViewportWidget)
        :Viewport(inViewportClient)
    {
        mViewportWidget=inViewportWidget;
    }

    void SceneViewport::ResizeFrame(uint32 NewWindowSizeX, uint32 NewWindowSizeY, EWindowMode NewWindowMode)
    {
        ResizeViewport(NewWindowSizeX,NewWindowSizeY,NewWindowMode);
    }
    void SceneViewport::ResizeViewport(uint32 NewSizeX, uint32 NewSizeY, EWindowMode NewWindowMode)
    {
        UpdateViewportRHI(false,NewSizeX,NewSizeY,NewWindowMode,EPixelFormat::PF_Unknown);
    }
    void SceneViewport::UpdateViewportRHI(bool bDestroyed, uint32 NewSizeX, uint32 NewSizeY, EWindowMode NewWindowMode, EPixelFormat PreferredPixelFormat)
    {
        SlaveRenderer*slaveRenderer=Application::Get()->mSlaveRenderer;
        mCGIViewport=(CGIViewport*)slaveRenderer->GetViewportResource(mViewportWidget->mWindow);
    }
}
